﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.IO;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;

namespace wxtools
{
    public class WxUtils
    {
        /// <summary>
        /// 获取好友头像
        /// </summary>
        /// <param name="username"></param>
        /// <returns></returns>
        public Image GetIcon(string username)
        {
            //https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxgeticon?seq=671050234&username=@75b4690f25ec31f59d1d2501a6ec1ffb&skey=@crypt_7855a35a_dde2932d28f24566eed68763d56b38a1&type=big
            byte[] bytes = WxTools.HttpGetBytes(string.Format("https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxgeticon?seq=0&username={0}&skey={1}&type=big", username, WxConfig.skey), true);

            return Image.FromStream(new MemoryStream(bytes));
        }

        /// <summary>
        /// 获取微信讨论组头像
        /// </summary>
        /// <param name="usename"></param>
        /// <returns></returns>
        public Image GetHeadImg(string username)
        {
            byte[] bytes = WxTools.HttpGetBytes(string.Format("https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxgeticon?seq=0&username={0}&skey={1}&type=big", username, WxConfig.skey), true);

            return Image.FromStream(new MemoryStream(bytes));
        }

        /// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="from"></param>
        /// <param name="to"></param>
        /// <param name="type"></param>
        public void SendMsg(string msg, string from, string to, int type)
        {
            string msg_json = "{{" +
            "\"BaseRequest\":{{" +
                "\"DeviceID\" : \"e441551176\"," +
                "\"Sid\" : \"{0}\"," +
                "\"Skey\" : \"{6}\"," +
                "\"Uin\" : \"{1}\"" +
            "}}," +
            "\"Msg\" : {{" +
                "\"ClientMsgId\" : {8}," +
                "\"Content\" : \"{2}\"," +
                "\"FromUserName\" : \"{3}\"," +
                "\"LocalID\" : {9}," +
                "\"ToUserName\" : \"{4}\"," +
                "\"Type\" : {5}" +
            "}}," +
            "\"rr\" : {7}" +
            "}}";
            msg_json = string.Format(msg_json, WxConfig.wxsid, WxConfig.wxuin, msg, from, to, type, WxConfig.skey, DateTime.Now.Millisecond, DateTime.Now.Millisecond, DateTime.Now.Millisecond);

            string send_result = WxTools.HttpPost(WxConfig.base_uri + "/webwxsendmsg?sid=" + WxConfig.wxsid + "&lang=zh_CN&pass_ticket=" + WxConfig.pass_ticket, msg_json);
        }

        /// <summary>
        /// 创建群
        /// </summary>
        /// <param name="UserNames"></param>
        /// <returns></returns>
        public bool createChatroom(List<string> UserNames)
        {
            string url = string.Format(WxConfig.base_uri + "/webwxcreatechatroom?pass_ticket={0}&lang=zh_CN&r={1}", WxConfig.pass_ticket, WxTools.GettTime());
            var pparams = new
            {
                MemberCount = UserNames.Count,
                MemberList = UserNames.Select(r => new { UserName = r }).ToList(),
                Topic = "",
                BaseRequest = WxConfig.BaseRequest
            };
            string data = Newtonsoft.Json.JsonConvert.SerializeObject(pparams);
            string retjson = wxtools.WxTools.HttpPost(url, data);
            JObject json = JObject.Parse(retjson);
            if ((json.GetValue("BaseResponse") as JObject).GetValue("Ret") + "" == "1")
            {
                return false;
            }
            WxConfig.ChatRoomName = json["ChatRoomName"].ToString();
            if (string.IsNullOrEmpty(WxConfig.ChatRoomName))
            {
                return false;
            }
            JArray MList = json.GetValue("MemberList") as JArray;
            foreach (JObject item in MList)
            {
                CheckFriend(MList);
            }
            return true;
        }

        /// <summary>
        /// 添加成员
        /// </summary>
        /// <param name="UserNames"></param>
        /// <returns></returns>
        public bool addMember(List<string> UserNames)
        {
            string url = string.Format(WxConfig.base_uri + "/webwxupdatechatroom?fun=addmember&pass_ticket={0}&r={1}", WxConfig.pass_ticket, WxTools.GettTime());
            var pparams = new
            {
                BaseRequest = WxConfig.BaseRequest,
                ChatRoomName = WxConfig.ChatRoomName,
                AddMemberList = string.Join(",", UserNames.ToArray()),
            };
            string data = Newtonsoft.Json.JsonConvert.SerializeObject(pparams);
            string retjson = wxtools.WxTools.HttpPost(url, data);
            JObject json = JObject.Parse(retjson);
            if ((json.GetValue("BaseResponse") as JObject).GetValue("Ret") + "" == "1")
            {
                return false;
            }
            JArray MList = json.GetValue("MemberList") as JArray;
            CheckFriend(MList);
            return true;
        }

        /// <summary>
        /// 检测状态
        /// </summary>
        /// <param name="MList"></param>
        private void CheckFriend(JArray MList)
        {
            foreach (JObject item in MList)
            {
                string status = item.GetValue("MemberStatus") + "";
                if (status == "4")
                {
                    WxConfig.DeletedList.Add(item.GetValue("UserName") + "");
                }
                if (status == "3")
                {
                    WxConfig.BlockedList.Add(item.GetValue("UserName") + "");
                }
            }
        }

        /// <summary>
        /// 删除组
        /// </summary>
        /// <param name="UserNames"></param>
        /// <returns></returns>
        public bool deleteMember(List<string> UserNames)
        {
            string url = string.Format(WxConfig.base_uri + "/webwxupdatechatroom?fun=delmember&pass_ticket={0}&lang=zh_CN&r={1}", WxConfig.pass_ticket, WxTools.GettTime());
            var pparams = new
            {
                BaseRequest = WxConfig.BaseRequest,
                ChatRoomName = WxConfig.ChatRoomName,
                DelMemberList = string.Join(",", UserNames.ToArray()),
            };
            string data = Newtonsoft.Json.JsonConvert.SerializeObject(pparams);
            string retjson = wxtools.WxTools.HttpPost(url, data);
            JObject json = JObject.Parse(retjson);
            if ((json.GetValue("BaseResponse") as JObject).GetValue("Ret") + "" == "1")
            {
                return false;
            }
            else
            {
                return true;
            }
        }

        /// <summary>
        /// 修改备注
        /// </summary>
        /// <param name="UserNames"></param>
        /// <returns></returns>
        public bool webWxOplog(string userName, string remarkName)
        {
            string url = string.Format(WxConfig.base_uri + "/webwxoplog?lang=zh_CN&pass_ticket={0}&r={1}", WxConfig.pass_ticket, WxTools.GettTime());
            var pparams = new
            {
                BaseRequest = WxConfig.BaseRequest,
                CmdId = 2,
                RemarkName = remarkName,
                UserName = userName
            };
            string data = Newtonsoft.Json.JsonConvert.SerializeObject(pparams);
            string retjson = wxtools.WxTools.HttpPost(url, data);
            JObject json = JObject.Parse(retjson);
            if ((json.GetValue("BaseResponse") as JObject).GetValue("Ret") + "" == "0")
            {
                return true;
            }
            else
            {
                return false;
            }
        }


        /// <summary>
        /// 微信同步检测
        /// </summary>
        /// <returns></returns>
        public string WxSyncCheck()
        {
            string sync_key = "";
            var list = WxConfig.SyncKey.GetValue("List") as JArray;
            foreach (JObject p in list)
            {
                sync_key += p.GetValue("Key") + "_" + p.GetValue("Val") + "%7C";
            }
            sync_key = sync_key.TrimEnd('%', '7', 'C');
            string _synccheck_url = string.Format(WxConfig.push_uri + "/synccheck?sid={0}&uin={1}&synckey={2}&r={3}&skey={4}&deviceid={5}", WxConfig.wxsid, WxConfig.wxuin, sync_key, WxTools.GettTime(), WxConfig.skey.Replace("@", "%40"), WxConfig.deviceid);
            string ret = WxTools.HttpGet(_synccheck_url + "&_=" + DateTime.Now.Ticks, "", false);
            return ret;
        }

        /// <summary>
        /// 微信同步
        /// </summary>
        /// <returns></returns>
        public JObject WxSync()
        {
            string sync_json = "{{\"BaseRequest\" : {{\"DeviceID\":\"{6}\",\"Sid\":\"{1}\", \"Skey\":\"{5}\", \"Uin\":\"{0}\"}},\"SyncKey\" : {{\"Count\":{2},\"List\":[{3}]}},\"rr\" :{4}}}";
            string sync_keys = "";
            var list = WxConfig.SyncKey.GetValue("List") as JArray;
            foreach (JObject p in list)
            {
                sync_keys += "{\"Key\":" + p.GetValue("Key").ToString() + ",\"Val\":" + p.GetValue("Val").ToString() + "},";
            }
            sync_keys = sync_keys.TrimEnd(',');
            sync_json = string.Format(sync_json, WxConfig.wxuin, WxConfig.wxsid, list.Count, sync_keys, WxTools.GettTime(), WxConfig.skey, WxConfig.deviceid);
            string sync_str = WxTools.HttpPost(WxConfig.push_uri + "/webwxsync?sid=" + WxConfig.wxsid + "&lang=zh_CN&skey=" + WxConfig.skey + "&pass_ticket=" + WxConfig.pass_ticket, sync_json, false);
            JObject sync_resul = JsonConvert.DeserializeObject(sync_str) as JObject;

            if (sync_resul["SyncKey"]["Count"].ToString() != "0")
            {
                WxConfig.SyncKey = sync_resul["SyncKey"] as JObject;
            }
            return sync_resul;
        }

        /// <summary>
        /// 登陆初始化
        /// </summary>
        /// <param name="xml"></param>
        public void webwxinit(string xml)
        {
            //"<error><ret>0</ret><message></message><skey>@crypt_7855a35a_7bfa4697173dedc47bb76c829b8c7c8f</skey><wxsid>/hXvUPx3ExhehKJm</wxsid><wxuin>2235275221</wxuin><pass_ticket>H9yqQuWyFlTzBgMsKkMibnjdcMrcU3TqKtw7zdzrL4eMPT6F%2F6wsBAKsU2psUK5h</pass_ticket><isgrayscale>1</isgrayscale></error>"
            System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
            doc.LoadXml(xml);

            string ret, isgrayscale;
            ret = doc.SelectSingleNode("//error/ret").InnerText;
            WxConfig.skey = doc.SelectSingleNode("//error/skey").InnerText;
            WxConfig.wxsid = doc.SelectSingleNode("//error/wxsid").InnerText;
            WxConfig.wxuin = doc.SelectSingleNode("//error/wxuin").InnerText;
            WxConfig.pass_ticket = doc.SelectSingleNode("//error/pass_ticket").InnerText;
            isgrayscale = doc.SelectSingleNode("//error/isgrayscale").InnerText;
            WxConfig.deviceid = "e5" + WxTools.GetTimeStamp(DateTime.Now);
            WxConfig.BaseRequest = new
            {
                Uin = WxConfig.wxuin,
                Sid = WxConfig.wxsid,
                Skey = WxConfig.skey,
                DeviceID = WxConfig.deviceid
            };
            string url = string.Format(WxConfig.base_uri + "/webwxinit?pass_ticket={0}&skey={1}&r={2}", WxConfig.pass_ticket, WxConfig.skey, WxTools.GettTime() + "");
            string postdata = "{\"BaseRequest\": " + Newtonsoft.Json.JsonConvert.SerializeObject(WxConfig.BaseRequest) + " }";
            string retjson = WxTools.HttpPost(url, postdata);
            JObject json = JObject.Parse(retjson);

            WxConfig.MyUser = json.GetValue("User") as JObject;
            WxConfig.SyncKey = json.GetValue("SyncKey") as JObject;
        }

        /// <summary>
        /// 获取联系人
        /// </summary>
        /// <returns></returns>
        public Dictionary<string, JObject> webwxgetcontact(ref int Seq)
        {
            string url = string.Format(WxConfig.base_uri + "/webwxgetcontact?pass_ticket={0}&seq={1}&skey={2}&r={3}", WxConfig.pass_ticket, Seq, WxConfig.skey, WxTools.GettTime() + "");
            //headers = {'content-type': 'application/json; charset=UTF-8'}
            string retjson = WxTools.HttpPost(url, "");
            //string retjson = WxTools.HttpGet(url,"");
            JObject json = JObject.Parse(retjson);
            JArray MemberList = json.GetValue("MemberList") as JArray;
            Seq = WxUtils.GetInt(json.GetValue("Seq") + "", 0);
            //# 倒序遍历,不然删除的时候出问题..
            string[] SpecialUsers = new string[]{"newsapp", "fmessage", "filehelper", "weibo", "qqmail", "tmessage", "qmessage", "qqsync", "floatbottle", "lbsapp", "shakeapp", "medianote", "qqfriend", "readerapp", "blogapp", "facebookapp", "masssendapp",
                            "meishiapp", "feedsapp", "voip", "blogappweixin", "weixin", "brandsessionholder", "weixinreminder", "wxid_novlwrv3lqwv11", "gh_22b87fa7cb3c", "officialaccounts", "notification_messages", "wxitil", "userexperience_alarm"};
            Dictionary<string, JObject> ret = new Dictionary<string, JObject>();
            ret.Clear();
            for (int i = 0; i < MemberList.Count; i++)
            {
                JObject Member = MemberList[i] as JObject;
                if ((int.Parse(Member["VerifyFlag"].ToString()) & 8) != 0)
                { // # 公众号/服务号
                    //MemberList.remove(Member);
                }
                else if (SpecialUsers.Contains(Member["UserName"].ToString()))
                {  //# 特殊账号
                    //MemberList.remove(Member);
                }
                else if (Member["UserName"].ToString().IndexOf("@@") != -1)
                { // # 群聊
                    WxConfig.GroupList.Add(Member["UserName"] + "", Member);
                }
                else if (Member["UserName"] + "" == WxConfig.MyUser["UserName"] + "")
                {  //# 自己
                    //MemberList.remove(Member);
                }
                else
                {
                    ret.Add(Member["UserName"] + "", Member);
                }
            }
            return ret;
        }

        public static int GetInt(string obj, int defdata)
        {
            int d;
            if (!int.TryParse(obj, out d))
            {
                d = defdata;
            }
            return d;
        }
    }
}
